const { getTable, setTable } = require('../../database')
const { STATUS, TABLE } = require('../../utils/constants')
const { format } = require('../../utils/date')
const { getTree } = require('../../utils/helper')

// 根据 id 获取 menu
async function getMenu (req) {
  const id = Number.parseInt(req.params.id)
  const menus = await getTable(TABLE.MENU)

  const menu = menus.find(v => v.id === id)

  if (!menu) {
    throw new Error('菜单不存在')
  }

  return { menus, menu }
}

// 获取菜单列表
exports.getMenus = async (req, res, next) => {
  let { page, limit, status } = req.query
  page = page ? Number.parseInt(page) : 1
  limit = limit ? Number.parseInt(limit) : 10
  status = ['0', '1'].includes(status) ? Number.parseInt(status) : null

  try {
    let menus = await getTable(TABLE.MENU)
    menus = menus.filter(v => !v.isDel)
    let list = getTree(menus)

    // 总条数
    const count = list.length

    // 筛选 排序 截取 转化时间格式
    const sortAndFilter = arr => {
      const res = status === null ? arr : arr.filter(v => v.status === status)

      res.forEach(v => {
        v._addTime = format(v._addTime)
        v._updateTime = format(v._updateTime)
        if (v.children && v.children.length > 0) {
          v.children = sortAndFilter(v.children)
        }
      })

      return res.sort((a, b) => a.order - b.order)
    }
    list = sortAndFilter(list).slice((page - 1) * limit, page * limit)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      data: {
        list,
        count
      }
    })
  } catch (error) {
    next(error)
  }
}

// 添加菜单
exports.createMenu = async (req, res, next) => {
  let {
    pid,
    name,
    icon = '',
    params = '',
    path = '',
    uniqueAuth = '',
    order,
    isHidden,
    status
  } = req.body
  pid = pid || 0

  try {
    const menus = await getTable(TABLE.MENU)

    // 校验父级是否存在
    const parent = menus.find(v => v.id === pid)
    if (!parent || parent.isDel === 1) {
      next('上级菜单不存在')
      return
    }

    // 生成 id 自增
    let id = 1
    if (menus.length > 0) {
      const menuIds = menus.map(v => v.id).sort()
      id = menuIds[menuIds.length - 1] + 1
    }

    const now = Date.now()

    const menu = {
      id,
      pid,
      name,
      icon,
      params,
      path,
      uniqueAuth,
      order,
      isHidden,
      status,
      isDel: 0,
      _addTime: now,
      _updateTime: now
    }

    menus.push(menu)

    await setTable(TABLE.MENU, menus)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      msg: 'ok'
    })
  } catch (error) {
    next(error)
  }
}

// 修改菜单
exports.updateMenu = async (req, res, next) => {
  let {
    pid = 0,
    name,
    icon = '',
    params = '',
    path = '',
    uniqueAuth = '',
    order,
    isHidden,
    status
  } = req.body
  pid = pid || 0

  try {
    const { menus, menu } = await getMenu(req)

    // 校验父级是否存在
    if (pid !== menus.pid) {
      const parent = menus.find(v => v.id === pid)
      if (!parent || parent.isDel === 1) {
        next('上级菜单不存在')
        return
      }
    }

    menu.pid = pid
    menu.name = name
    menu.icon = icon
    menu.params = params
    menu.path = path
    menu.uniqueAuth = uniqueAuth
    menu.order = order
    menu.isHidden = isHidden
    menu.status = status
    menu._updateTime = Date.now()

    await setTable(TABLE.MENU, menus)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      msg: 'ok'
    })
  } catch (error) {
    next(error)
  }
}

// 获取菜单
exports.getMenu = async (req, res, next) => {
  try {
    const { menu } = await getMenu(req)

    menu._addTime = format(menu._addTime)
    menu._updateTime = format(menu._updateTime)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      data: menu
    })
  } catch (error) {
    next(error)
  }
}

// 删除菜单
exports.deleteMenu = async (req, res, next) => {
  try {
    const { menus, menu } = await getMenu(req)

    menu.isDel = 1
    menu._updateTime = Date.now()
    await setTable(TABLE.MENU, menus)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      msg: 'ok'
    })
  } catch (error) {
    next(error)
  }
}

// 修改菜单状态
exports.setMenuStatus = async (req, res, next) => {
  const status = Number.parseInt(req.params.status)

  try {
    const { menus, menu } = await getMenu(req)

    menu.status = status
    menu._updateTime = Date.now()
    await setTable(TABLE.MENU, menus)

    // 响应结果
    res.json({
      status: STATUS.SUCCESS,
      msg: 'ok'
    })
  } catch (error) {
    next(error)
  }
}
